<template>
  <div class="audit-log">
    <el-page-header title="日志管理">
      <template #content>
        <span class="page-header-content">审计日志</span>
      </template>
    </el-page-header>

    <div class="log-content">
      <!-- 搜索栏 -->
      <el-card class="search-card">
        <el-form :model="searchForm" ref="searchFormRef" inline>
          <el-form-item label="审计类型" prop="auditType">
            <el-select
              v-model="searchForm.auditType"
              placeholder="请选择审计类型"
              clearable
              style="width: 160px"
            >
              <el-option label="数据变更" value="data" />
              <el-option label="权限变更" value="permission" />
              <el-option label="配置变更" value="config" />
              <el-option label="状态变更" value="status" />
            </el-select>
          </el-form-item>
          <el-form-item label="操作人" prop="operator">
            <el-input
              v-model="searchForm.operator"
              placeholder="请输入操作人"
              clearable
            />
          </el-form-item>
          <el-form-item label="所属模块" prop="module">
            <el-select
              v-model="searchForm.module"
              placeholder="请选择所属模块"
              clearable
              style="width: 160px"
            >
              <el-option label="客户管理" value="customer" />
              <el-option label="贷款管理" value="loan" />
              <el-option label="产品管理" value="product" />
              <el-option label="系统设置" value="system" />
            </el-select>
          </el-form-item>
          <el-form-item label="操作时间" prop="timeRange">
            <el-date-picker
              v-model="searchForm.timeRange"
              type="datetimerange"
              range-separator="至"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              value-format="YYYY-MM-DD HH:mm:ss"
              :shortcuts="dateShortcuts"
            />
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="handleSearch">查询</el-button>
            <el-button @click="handleReset">重置</el-button>
            <el-button type="success" @click="handleExport">导出日志</el-button>
          </el-form-item>
        </el-form>
      </el-card>

      <!-- 日志表格 -->
      <el-card class="table-card">
        <el-table
          :data="tableData"
          style="width: 100%"
          v-loading="loading"
          border
          stripe
        >
          <el-table-column type="index" label="序号" width="60" align="center" />
          <el-table-column prop="auditType" label="审计类型" width="120">
            <template #default="scope">
              <el-tag :type="getAuditTypeTag(scope.row.auditType)">
                {{ getAuditTypeLabel(scope.row.auditType) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="operator" label="操作人" width="120">
            <template #default="scope">
              <el-tooltip
                :content="scope.row.operatorInfo"
                placement="top"
                effect="light"
              >
                <span>{{ scope.row.operator }}</span>
              </el-tooltip>
            </template>
          </el-table-column>
          <el-table-column prop="module" label="所属模块" width="120" />
          <el-table-column prop="operation" label="操作内容" min-width="200" show-overflow-tooltip />
          <el-table-column prop="objectType" label="对象类型" width="120" />
          <el-table-column prop="objectId" label="对象ID" width="120" />
          <el-table-column prop="ip" label="IP地址" width="140" />
          <el-table-column prop="createTime" label="操作时间" width="180" />
          <el-table-column label="操作" width="120" fixed="right">
            <template #default="scope">
              <el-button
                link
                type="primary"
                @click="handleViewDetail(scope.row)"
              >
                详情
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <div class="pagination">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[10, 20, 50, 100]"
            :total="total"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </el-card>

      <!-- 详情弹窗 -->
      <el-dialog
        v-model="detailVisible"
        title="审计日志详情"
        width="800px"
        destroy-on-close
      >
        <el-descriptions :column="2" border>
          <el-descriptions-item label="审计类型">
            <el-tag :type="getAuditTypeTag(currentLog.auditType)">
              {{ getAuditTypeLabel(currentLog.auditType) }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="操作人">
            {{ currentLog.operator }}
          </el-descriptions-item>
          <el-descriptions-item label="所属模块">
            {{ currentLog.module }}
          </el-descriptions-item>
          <el-descriptions-item label="操作时间">
            {{ currentLog.createTime }}
          </el-descriptions-item>
          <el-descriptions-item label="IP地址">
            {{ currentLog.ip }}
          </el-descriptions-item>
          <el-descriptions-item label="操作地点">
            {{ currentLog.location }}
          </el-descriptions-item>
          <el-descriptions-item label="对象类型">
            {{ currentLog.objectType }}
          </el-descriptions-item>
          <el-descriptions-item label="对象ID">
            {{ currentLog.objectId }}
          </el-descriptions-item>
          <el-descriptions-item label="操作内容" :span="2">
            {{ currentLog.operation }}
          </el-descriptions-item>
          <el-descriptions-item label="变更前数据" :span="2">
            <pre class="code-block">{{ formatJson(currentLog.beforeData) }}</pre>
          </el-descriptions-item>
          <el-descriptions-item label="变更后数据" :span="2">
            <pre class="code-block">{{ formatJson(currentLog.afterData) }}</pre>
          </el-descriptions-item>
          <el-descriptions-item label="备注" :span="2">
            {{ currentLog.remark }}
          </el-descriptions-item>
        </el-descriptions>

        <!-- 数据对比 -->
        <div v-if="showDiff" class="diff-section">
          <div class="section-title">数据对比</div>
          <el-table
            :data="diffData"
            style="width: 100%"
            border
            size="small"
          >
            <el-table-column prop="field" label="字段" width="180" />
            <el-table-column prop="before" label="变更前">
              <template #default="scope">
                <span :class="{ 'diff-removed': scope.row.changed }">
                  {{ scope.row.before }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="after" label="变更后">
              <template #default="scope">
                <span :class="{ 'diff-added': scope.row.changed }">
                  {{ scope.row.after }}
                </span>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import { ref, reactive, computed } from 'vue'
import { ElMessage } from 'element-plus'

export default {
  name: 'AuditLog',
  setup() {
    // 搜索表单
    const searchForm = reactive({
      auditType: '',
      operator: '',
      module: '',
      timeRange: []
    })

    // 日期快捷选项
    const dateShortcuts = [
      {
        text: '最近一小时',
        value: () => {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000)
          return [start, end]
        }
      },
      {
        text: '今天',
        value: () => {
          const end = new Date()
          const start = new Date()
          start.setHours(0, 0, 0, 0)
          return [start, end]
        }
      },
      {
        text: '最近三天',
        value: () => {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 3)
          return [start, end]
        }
      },
      {
        text: '最近一周',
        value: () => {
          const end = new Date()
          const start = new Date()
          start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
          return [start, end]
        }
      }
    ]

    // 表格数据
    const loading = ref(false)
    const currentPage = ref(1)
    const pageSize = ref(10)
    const total = ref(100)
    const tableData = ref([
      {
        auditType: 'data',
        operator: 'admin',
        operatorInfo: 'admin - 系统管理员',
        module: '客户管理',
        operation: '修改客户基本信息',
        objectType: '客户',
        objectId: '1001',
        ip: '192.168.1.100',
        location: '广东省深圳市',
        createTime: '2024-03-01 10:30:45',
        beforeData: {
          name: '张三',
          phone: '13800138000',
          email: 'zhangsan@example.com'
        },
        afterData: {
          name: '张三',
          phone: '13800138001',
          email: 'zhangsan@company.com'
        },
        remark: '更新联系方式'
      }
    ])

    // 详情弹窗
    const detailVisible = ref(false)
    const currentLog = ref({})

    // 是否显示数据对比
    const showDiff = computed(() => {
      return currentLog.value.beforeData && currentLog.value.afterData
    })

    // 数据对比列表
    const diffData = computed(() => {
      if (!showDiff.value) return []

      const before = currentLog.value.beforeData
      const after = currentLog.value.afterData
      const fields = new Set([...Object.keys(before), ...Object.keys(after)])

      return Array.from(fields).map(field => ({
        field,
        before: before[field],
        after: after[field],
        changed: before[field] !== after[field]
      }))
    })

    // 审计类型标签
    const getAuditTypeTag = (type) => {
      const map = {
        data: 'primary',
        permission: 'danger',
        config: 'warning',
        status: 'success'
      }
      return map[type] || 'info'
    }

    // 审计类型文本
    const getAuditTypeLabel = (type) => {
      const map = {
        data: '数据变更',
        permission: '权限变更',
        config: '配置变更',
        status: '状态变更'
      }
      return map[type] || type
    }

    // 格式化JSON
    const formatJson = (json) => {
      try {
        return JSON.stringify(json, null, 2)
      } catch (e) {
        return json
      }
    }

    // 查询
    const handleSearch = () => {
      loading.value = true
      // TODO: 实现查询逻辑
      setTimeout(() => {
        loading.value = false
      }, 500)
    }

    // 重置
    const handleReset = () => {
      searchForm.auditType = ''
      searchForm.operator = ''
      searchForm.module = ''
      searchForm.timeRange = []
      handleSearch()
    }

    // 导出
    const handleExport = () => {
      ElMessage.success('日志导出成功')
    }

    // 查看详情
    const handleViewDetail = (row) => {
      currentLog.value = row
      detailVisible.value = true
    }

    // 分页
    const handleSizeChange = (val) => {
      pageSize.value = val
      handleSearch()
    }

    const handleCurrentChange = (val) => {
      currentPage.value = val
      handleSearch()
    }

    return {
      searchForm,
      dateShortcuts,
      loading,
      currentPage,
      pageSize,
      total,
      tableData,
      detailVisible,
      currentLog,
      showDiff,
      diffData,
      getAuditTypeTag,
      getAuditTypeLabel,
      formatJson,
      handleSearch,
      handleReset,
      handleExport,
      handleViewDetail,
      handleSizeChange,
      handleCurrentChange
    }
  }
}
</script>

<style scoped>
.audit-log {
  padding: 20px;
}

.page-header-content {
  font-size: 20px;
  font-weight: bold;
}

.log-content {
  margin-top: 20px;
}

.search-card {
  margin-bottom: 20px;
}

.table-card {
  margin-bottom: 20px;
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.code-block {
  margin: 0;
  padding: 8px;
  background-color: #f5f7fa;
  border-radius: 4px;
  font-family: monospace;
  white-space: pre-wrap;
  word-break: break-all;
}

.diff-section {
  margin-top: 20px;
  border-top: 1px solid #dcdfe6;
  padding-top: 20px;

  .section-title {
    font-size: 16px;
    font-weight: bold;
    margin-bottom: 10px;
  }

  .diff-removed {
    color: #f56c6c;
    background-color: #fef0f0;
    padding: 2px 4px;
    border-radius: 2px;
  }

  .diff-added {
    color: #67c23a;
    background-color: #f0f9eb;
    padding: 2px 4px;
    border-radius: 2px;
  }
}

:deep(.el-card__body) {
  padding: 20px;
}
</style> 